/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package simulation;

import java.util.logging.Level;
import java.util.logging.Logger;
import util.DistributionFactory;

/**
 *
 * @author Gravena
 */
public class VMTask implements Runnable {
    private String binary; /* Name of the binary, without path, since the binary MUST be in a special folder in order to be a valid execution for the COMEVIM */
    private double[] times; /* Times in witch each execution needs to happen */
    private String[] args; /* Arguments for the execution */
    private double counter; /* Count the elapsed seconds on the exec method */        
    private Distribution dist;
    private int samples;

    public VMTask() {
        this.binary = "hello";
        this.args = null;
        double[] param = {1.0};
        this.dist = DistributionFactory.getInstance("Exponential", param);
    }
    
    public VMTask(String binary, String[] args, Distribution dist, int samples) {
        this.binary = binary;
        this.args = args;
        this.dist = dist;
        this.samples = samples;
    }

    public int getSamples() {
        return samples;
    }

    public void setSamples(int samples) {
        this.samples = samples;
    }
    
    
    
    public Distribution getDist() {
        return dist;
    }

    public void setDist(Distribution dist) {
        this.dist = dist;
    }        
    
    public String[] getArgs() {
        return args;
    }

    public void setArgs(String[] args) {
        this.args = args;
    }

    public String getBinary() {
        return binary;
    }

    public void setBinary(String binary) {
        this.binary = binary;
    }

    public double[] getTimes() {
        return times;
    }

    public void setTimes(double[] times) {
        this.times = times;
    }
    
    /**
     * Execute this VMTask object
     */
    @Override
    public void run() {
        int current_index = 0;
        this.counter = 0.0;
        boolean control = true;
        this.times = this.dist.getTimes(10); /* Generate a event pattern */
        Exponential.sort(this.times);
        
        
        /* While there are execution to be made */
        while(control) {            
            try {
                /* Sleeps the thread to increment the time counter in 0,1 seconds a time */
                Thread.sleep(100);
                this.counter += 0.1;
                
                /* If the counter time is equal or greater then the time stored in the current_index */
                if(this.times[current_index]*60.0 <= this.counter) {
                    
                    /* Execute, but in a new thread, so the counter can goes on without loose it's consistency */
                    System.out.println("Executing #" + current_index + " at " + this.counter + "[" + this.times[current_index]*60.0 + "]");
                    new Thread(new TestExecutor(binary,args)).start();
                    
                    /* Increment the current index and checks if there are more execution to be made */
                    current_index++;
                    if(current_index == this.times.length) {
                        control = false;
                    }
                }
            } catch (InterruptedException ex) {
                Logger.getLogger(VMTask.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }
    
    public static void main(String args[]) {
        VMTask task = new VMTask();        
        Exponential exp = new Exponential(1.0);
        
        task.setBinary("hello.exe");
        String arguments[] = {"Teste"};
        task.setArgs(arguments);        
        task.setTimes(exp.getPoissonProcess(10));
        
        Exponential.sort(task.getTimes());
        System.out.println(Exponential.calcMean(task.getTimes()));
        Exponential.printArray(task.getTimes());
        
        task.run();
    }    
    
    @Override
    public String toString() {
        return "Binary: " + this.binary + "\nDistribution: " + this.dist + "\nArgs: " + this.args;
    }
    
    
}
